package com.free4inno.knowledgems.controller;

import com.free4inno.knowledgems.dao.GroupInfoDAO;
import com.free4inno.knowledgems.dao.LabelInfoDAO;
import com.free4inno.knowledgems.dao.ResourceDAO;
import com.free4inno.knowledgems.dao.SpecResourceDAO;
import com.free4inno.knowledgems.dao.UserDAO;
import com.free4inno.knowledgems.domain.GroupInfo;
import com.free4inno.knowledgems.domain.LabelInfo;
import com.free4inno.knowledgems.domain.Resource;
import com.free4inno.knowledgems.domain.SpecResource;
import com.free4inno.knowledgems.domain.User;
import com.free4inno.knowledgems.constants.UserConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.sql.Timestamp;
import java.util.*;

/**
 * Author: HaoYi.
 * Date: 2021/02/07.
 */

@Slf4j
@Controller
@RequestMapping("/specresource")
public class SpecResourceController {

    @Autowired
    private ResourceDAO resourceDao;

    @Autowired
    private UserDAO userDao;

    @Autowired
    private LabelInfoDAO labelInfoDao;

    @Autowired
    private GroupInfoDAO groupInfoDao;

    @Autowired
    private SpecResourceDAO specResourceDao;

    //每一页的结果显示数量
    int size = 10;

    @RequestMapping("")
    public String specialResourceData(@RequestParam("type") Integer type,
                                      @RequestParam("page") int page, Map param, HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "推荐资源(specialResourceData)"+"----"+session.getAttribute(UserConstants.USER_ID));
        //确定type
        List<SpecResource> specResourceList = specResourceDao.findAllByType(type);
        //按时间排序（新的在前面）
        specResourceList.sort(new Comparator<SpecResource>() {
            @Override
            public int compare(SpecResource o1, SpecResource o2) {
                return o2.getInsert_time().compareTo(o1.getInsert_time());
            }
        });
        //按order排序（小的在前面）
        specResourceList.sort(new Comparator<SpecResource>() {
            @Override
            public int compare(SpecResource o1, SpecResource o2) {
                return o1.getOrder() - o2.getOrder();
            }
        });
        List<Integer> resourceIdList = new ArrayList<>();
        for (SpecResource specResource : specResourceList) {
            resourceIdList.add(specResource.getResourceId());
        }
//        Pageable pageable = PageRequest.of(page, size);
//        Page<Resource> resourcePage = resourceDao.findByIdIn(pageable,resourceIdList);
//        long resourceNum = resourcePage.getTotalElements();
//        System.out.print(resourcePage);
        long resourceNum = resourceIdList.size();
        long pageSize;
        //pageSize
        if (resourceNum % 10 == 0) {
            pageSize = resourceNum / 10;
        } else {
            pageSize = resourceNum / 10 + 1;
        }
        //将所有数据返回为List
        List<Resource> resourceList = new ArrayList<Resource>();
        for (int i = 10 * page; i < 10 * (page + 1); i++) {
            if (i < resourceNum) {
                resourceList.add(resourceDao.findById(resourceIdList.get(i)).orElse(new Resource()));
            } else {
                break;
            }
        }
        // List<Resource> resourceList = resourcePage.getContent();

        // 1. build 3 hash set to De-duplication : user, label, group
        HashSet<Integer> usersId = new HashSet<>();
        HashSet<Integer> labelsId = new HashSet<>();
        HashSet<Integer> groupsId = new HashSet<>();
        for (Resource resource : resourceList) {
            // 1.1. user
            int userId = resource.getUserId();
            usersId.add(userId);
            // 1.2. label
            if (resource.getLabelId() != null && !resource.getLabelId().equals("")) {
                String[] label = resource.getLabelId().split(",|，");
                for (String s : label) {
                    int labelId = (s == "" ? 0 : Integer.parseInt(s));
                    labelsId.add(labelId);
                }
            }
            // 1.3. group
            if (resource.getGroupId() != null && !resource.getGroupId().equals("")) {
                String[] group = resource.getGroupId().split(",|，");
                for (String s : group) {
                    int groupId = (s == "" ? 0 : Integer.parseInt(s));
                    groupsId.add(groupId);
                }
            }
        }

        // 2. build 3 hash map to save all string names
        HashMap<Integer, String> usersName = new HashMap<>();
        HashMap<Integer, String> labelsName = new HashMap<>();
        HashMap<Integer, String> groupsName = new HashMap<>();
        // 2.1. user
        for (Integer userId : usersId){
            User user = userDao.findById(userId).orElse(new User());
            usersName.put(userId, user.getRealName());
        }
        // 2.2. label
        for (Integer labelId : labelsId){
            LabelInfo labelInfo = labelInfoDao.findById(labelId).orElse(new LabelInfo());
            if (labelInfo.getLabelName() != null) {
                String ln = labelInfo.getLabelName();
                labelsName.put(labelId, ln);
            } else {
                labelsName.put(labelId, "未知标签" + labelId);
            }
        }
        // 2.3. group
        for (Integer groupId : groupsId){
            GroupInfo groupInfo = groupInfoDao.findById(groupId).orElse(new GroupInfo());
            if (groupInfo.getGroupName() != null) {
                String gn = groupInfo.getGroupName();
                groupsName.put(groupId, gn);
            } else {
                groupsName.put(groupId, "未知群组" + groupId);
            }
        }

        resourceList.forEach(resource -> {
            String text = resource.getText();
            String title = resource.getTitle();
            resource.setText(text.replaceAll("<.*?>", ""));
            resource.setTitle(title.replaceAll("<.*?>", ""));
            //取作者名
            resource.setUserName(usersName.get(resource.getUserId()));
            //取群组名
            String groupNames = "";
            if (resource.getGroupId() != null && !resource.getGroupId().equals("")) {
                List<String> groupIdList = Arrays.asList(resource.getGroupId().split(",|，"));
                for (String s : groupIdList) {
                    int groupId = (s.equals("") ? 0 : Integer.parseInt(s));
                    groupNames = groupNames + "," + groupsName.get(groupId);
                }
                groupNames = groupNames.substring(1);
            } else {
                groupNames = "该资源无群组";
            }
            resource.setGroupName(groupNames);
            //取标签名
            String labelNames = "";
            if (resource.getLabelId() != null && !resource.getLabelId().equals("")) {
                List<String> labelIdList = Arrays.asList(resource.getLabelId().split(",|，"));
                for (String item : labelIdList) {
                    int labelId = (item.equals("") ? 0 : Integer.parseInt(item));
                    labelNames = labelNames + "," + labelsName.get(labelId);
                }
                labelNames = labelNames.substring(1);
            } else {
                labelNames = "该资源无标签";
            }
            resource.setLabelName(labelNames.toString());
            //取特殊资源信息
            resource.setSpecType(type);
            //取排序信息
            SpecResource specResource = specResourceDao.findByResourceIdAndType(resource.getId(), type).orElse(new SpecResource());
            resource.setSpecOrder(specResource.getOrder());
        });
        param.put("resourceList", resourceList);
        param.put("resourceNum", resourceNum);
        param.put("pageSize", pageSize);
        log.info(this.getClass().getName() + "----out----" + "返回获取到的推荐资源"+"----"+session.getAttribute(UserConstants.USER_ID));
        return "/resource/_result";
    }

    @ResponseBody
    @RequestMapping("deleteSpec")
    public String deleteResourceData(@RequestParam("type") Integer type,
                                     @RequestParam("resourceId") Integer resourceId,
                                     HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "取消推荐(deleteSpec)" + "----" + session.getAttribute(UserConstants.USER_ID));
        String result = "";
        try {
            specResourceDao.deleteByResourceIdAndType(resourceId, type);
            log.info(this.getClass().getName() + "----out----" + "取消推荐成功" + "----" + session.getAttribute(UserConstants.USER_ID));
            result = "success";
        } catch (Exception e) {
            log.info(this.getClass().getName() + "----out----" + "取消推荐错误" + "----" + session.getAttribute(UserConstants.USER_ID));
            result = "error";
        }
        return result;
    }

    @ResponseBody
    @RequestMapping("crudSpec")
    public Map<String, Object> addSpecResource(@RequestParam("type") Integer type,
                                               @RequestParam("resourceId") Integer resourceId,
                                               @RequestParam("order") Integer order,
                                               HttpSession session) {
        log.info(this.getClass().getName() + "----in----" + "新增推荐(crudSpec)" + "----" + session.getAttribute(UserConstants.USER_ID));
        Map<String, Object> jsonObject = new HashMap<>();
        try {
            Optional<SpecResource> specResourceOptional = specResourceDao.findByResourceIdAndType(resourceId, type);
            if (specResourceOptional.isPresent()) {
                SpecResource specResource = specResourceOptional.get();
                specResource.setOrder(order);
                specResource.setInsert_time(new Timestamp(new Date().getTime()));
                specResourceDao.save(specResource);
            } else {
                SpecResource specResource = new SpecResource();
                specResource.setResourceId(resourceId);
                specResource.setOrder(order);
                specResource.setType(type);
                specResource.setInsert_time(new Timestamp(new Date().getTime()));
                specResourceDao.save(specResource);
            }
            jsonObject.put("msg", "SUCCESS");
            jsonObject.put("order", order);
            log.info(this.getClass().getName() + "----out----" + "新增推荐成功" + "----" + session.getAttribute(UserConstants.USER_ID));
        } catch (Exception e) {
            jsonObject.put("msg", "ERROR");
            log.info(this.getClass().getName() + "----out----" + "新增推荐错误" + "----" + session.getAttribute(UserConstants.USER_ID));
        }
        return jsonObject;
    }
}
